<template>
  <div class="container">
    <div class="app-container">
      <!-- 按钮 -->
      <el-row style="padding: 15px">
        <el-button size="mini" type="primary" @click="showDialog">添加角色</el-button>
      </el-row>
      <!-- 表格 -->
      <el-table :data="roleList">
        <el-table-column prop="name" label="角色">
          <template v-slot="{row}">
            <el-input v-if="row.isEdit" v-model="row.formEdit.name" placeholder="请输入角色名称" />
            <span v-else>{{ row.name }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="state" label="启用">
          <template v-slot="{row}">
            <el-switch
              v-if="row.isEdit"
              v-model="row.formEdit.state"
              :active-value="1"
              :inactive-value="0"
            />
            <span v-else>{{ row.state===1?'已启用': row.state===0?'未启用':'未知' }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="description" label="描述">
          <template v-slot="{row}">
            <el-input v-if="row.isEdit" v-model="row.formEdit.description" type="textarea" />
            <span v-else>{{ row.description }}</span>
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template v-slot="{row}">
            <div v-if="row.isEdit">
              <el-button size="mini" type="primary" @click="confirm(row)">确定</el-button>
              <el-button size="mini" @click="cancel(row)">取消</el-button>
            </div>
            <div v-else>
              <el-button type="text" @click="assignPerm(row.id)">分配权限</el-button>
              <el-button type="text" @click="edit(row)">编辑</el-button>
              <el-popconfirm
                style="margin-left: 10px"
                title="这是一段内容确定删除吗？"
                @onConfirm="delConfirm(row.id)"
              >
                <el-button slot="reference" type="text">删除</el-button>
              </el-popconfirm>
            </div>
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页器 -->
      <el-row type="flex" justify="end">
        <el-pagination
          :total="total"
          :page-size="pageSize"
          layout="prev, pager, next"
          @current-change="currentChange"
        />
      </el-row>
      <!-- 新增 -->
      <el-dialog title="新增角色" :visible="isShow" @close="close">
        <el-form ref="form" :model="formData" :rules="rules" label-width="100px">
          <el-form-item label="角色名称" prop="name">
            <el-input v-model="formData.name" />
          </el-form-item>
          <el-form-item label="启用">
            <el-switch
              v-model="formData.state"
              :active-value="1"
              :inactive-value="0"
            />
          </el-form-item>
          <el-form-item label="角色描述" prop="description">
            <el-input v-model="formData.description" type="textarea" />
          </el-form-item>
          <el-form-item>
            <el-row type="flex" justify="center">
              <el-button type="primary" @click="submit">确定</el-button>
              <el-button @click="close">取消</el-button>
            </el-row>
          </el-form-item>
        </el-form>
      </el-dialog>
      <!-- 分配权限 -->
      <el-dialog title="分配权限" :visible.sync="showPerm">
        <!--  show-checkbox: 显示复选框
        check-strictly：父子节点互不关联
         -->
        <el-tree ref="permTree" node-key="id" show-checkbox check-strictly :data="permList" :props="{label: 'name'}" />
        <template v-slot:footer>
          <el-row type="flex" justify="center">
            <el-button type="primary" size="mini" @click="permSubmit">确定</el-button>
            <el-button size="mini" @click="closePerm">取消</el-button>
          </el-row>
        </template>
      </el-dialog>
    </div>
  </div>
</template>
<script>
/**
 * 功能：实现角色的增删改查
 * 总体思路：先静后动
 * 静：先完成静态结构
 * 动：功能
 * 1、查 --- 查询数据--渲染列表 -- 实现分页
 * 2、增 --- 新增角色
 *
 * 完成以上功能后，重新吧今天的内容再写一遍
 *
 *
 * 需求3：完成编辑功能
 *  分析：点击“编辑”按钮，在表格中把文本内容改为表单并且表单内容有回显，
 * 用户修改表单内容，最后点击确定按钮实现修改
 * 拆解步骤：
 * 1、给“编辑”按钮绑定点击事件
 * 2、在点击的事件处理函数控制当前行表单的显示
 *    2-1、准备好表单
 *    2-2、准备一个变量来控制表单的显示隐藏
 *      注意：这个变量只能控制当前行的表单，不能影响其他行的表单
 *    2-3、在点击事件处理函数中控制表单的显示隐藏了
 * 3、实现表单中内容的回显
 * 4、获取表单修改后的内容 --- v-model
 * 5、给“确定”按钮绑定点击事件
 * 6、封装修改的接口函数
 * 7、在确定的事件处理函数中调用接口函数 实现修改
 *
 * 难点：控制表单显示隐藏的变量如何声明 以及 双向绑定的变量如何声明
 *
 *
 *
 * 需求4：实现删除角色功能
 * 分析：点击删除按钮，显示询问框，最后点击确定实现删除
 * 拆解步骤：
    1、利用popconfirm组件显示删除按钮 -- 并实现询问框
    2、给询问框中的确定按钮绑定点击事件（onConfirm事件）
      注意：elementui文档中提供的confirm事件是错误的
    3、封装接口函数
    4、在onConfirm事件处理函数中调用接口实现删除
    5、删除成功后更新列表
      注意：判断--删除的最后一条数据需要把当前页码减一
    请求上一页的数据

    难点：1、elementui文档中提供的confirm事件是错误的
         2、删除的最后一条数据后更新列表空白问题
 *
 * */
import { roleList, addRole, updateRole, deleteRole, assignPerm, roleDetails } from '@/api/role'
import { permissionList } from '@/api/permission'
import { transListToTreeData } from '@/utils'
export default {
  name: 'Role',
  data() {
    return {
      showPerm: false, // 分配权限弹窗
      permList: [], // 权限列表
      total: 0,
      pageSize: 5,
      page: 1,
      roleList: [{
        id: 1,
        name: '人事经理',
        description: '负责整合人事部门',
        state: 1, // 1 表示已启用 0 表示未启用
        isEdit: false
      }],
      isShow: false,
      formData: {
        name: '',
        description: '',
        state: 0
      },
      rules: {
        description: [
          { required: true, message: '请填写描述', trigger: blur }
        ],
        name: [
          { required: true, message: '请填写名称', trigger: blur }
        ]
      }
    }
  },
  created() {
    this.getRoleList()
    this.getPermissions()
  },
  methods: {
    async getPermissions() {
      const res = await permissionList()
      this.permList = transListToTreeData(res, 0)
    },
    // 取消分配权限
    closePerm() {
      this.showPerm = false
    },
    // 分配权限
    async assignPerm(id) {
      this.roleId = id // 保存当前点击的角色id
      this.showPerm = true
      // 获取角色默认权限信息
      const res = await roleDetails(id)
      // 权限回显
      this.$refs.permTree.setCheckedKeys(res.permIds)
    },
    // 确定分配权限
    async permSubmit() {
      // 获取用户选择的权限id
      const res = this.$refs.permTree.getCheckedKeys()
      // 调用接口分配权限
      await assignPerm({
        id: this.roleId,
        permIds: res
      })
      this.$message.success('分配权限成功！')
      this.closePerm()
    },
    // 确定删除
    async delConfirm(id) {
      // console.log(id)
      await deleteRole(id)
      this.$message.success('删除成功')
      // 更新列表
      // 判断此刻删除的是否为当前页的最后一条数据，
      // 如果是更新列表的时候则需要请求上一页的数据
      if (this.roleList.length === 1) {
        this.page--
      }
      this.getRoleList()
    },
    // 编辑
    edit(row) {
      console.log('编辑')
      row.isEdit = true
    },
    // 取消编辑
    cancel(row) {
      row.isEdit = false
      row.formEdit = {
        id: row.id,
        name: row.name,
        state: row.state,
        description: row.description
      }
    },
    // 确定修改
    async confirm(row) {
      await updateRole(row.formEdit)
      this.$message.success('修改成功！')
      // 更新列表中当前行数据
      // row.name = row.formEdit.name
      // row.state = row.formEdit.state
      // row.description = row.formEdit.description
      // Object.assign 是原生js的方法，用于合并对象
      // 语法：Object.assign(targetObj, newObj)
      Object.assign(row, {
        name: row.formEdit.name,
        state: row.formEdit.state,
        description: row.formEdit.description
      })
      this.cancel(row)
    },
    async getRoleList() {
      const res = await roleList({
        page: this.page,
        pagesize: this.pageSize
      })
      // 方式一
      // res.rows.forEach(item => {
      //   // 为每一行对象添加isEdit属性 控制当前行的表单显示隐藏
      //   item.isEdit = false
      //   // 为每一行对象添加 表单数据
      //   item.formEdit = {
      //     ...item
      //   }
      // })
      this.roleList = res.rows
      this.roleList.forEach(item => {
        // 新增加的属性 vue监控不到
        // 方式二
        // vue转门提供了一个方法解决这个问题: $set(对象, 属性，值)
        // item.isEdit = false
        this.$set(item, 'isEdit', false)
        this.$set(item, 'formEdit', {
          ...item
        })
      })
      this.total = res.total
    },
    // 分页
    currentChange(page) {
      // console.log(page)
      this.page = page
      this.getRoleList()
    },
    // 显示弹窗
    showDialog() {
      this.isShow = true
    },
    // 确定新增
    async submit() {
      await this.$refs.form.validate()
      await addRole(this.formData)
      this.$message.success('添加成功！')
      this.close()
      this.getRoleList()
    },
    close() {
      this.$refs.form.resetFields()
      this.isShow = false
    }
  }
}
</script>
